﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace MMDemo
{
    /*
       *	枚举当前可执行类型
       */
    public enum OperateTypeBinTree
    {
        CreTree,
        PreOrder,
        InOrder,
        PostOrder,
        Hoffman,
    }
    class AnimationBinTree:InterfaceDataStructs
    {
        /// <summary>
        /// 类成员
        /// </summary>
        private Form Animation_Form = null;//演示窗体，用于构造函数的初始化
        private int Animation_width = 0;//演示窗体的宽度
        private int Animation_height = 0;//演示窗体的高度
        public Bitmap BufferBmp = null;//双缓冲画布
        private Graphics BufferGrap = null;//画笔
        private DrawHandler RefreshHandler = null;

        private char[] BinTree_Data;//二叉树元素（顺序表存储结构）
        private BinTreeNode BinTreeData;//二叉树（链表存储结构）
        private const int MAX_SIZE = 16; //二叉树节点数的最大数据容量

        String path = Application.StartupPath;
        private int NSize = 30;
        private int NCOffset = 30;
        private int PosSize = 30;
        private Bitmap NodeBmp = null;
        private Bitmap PosBmp = null;
        private Bitmap HoffmanBmp = null;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="An_Form"></param>
        /// <param name="refreshHandler"></param>
        /// <param name="An_Width"></param>
        /// <param name="An_Height"></param>
        public AnimationBinTree(Form An_Form, DrawHandler refreshHandler, int An_Width, int An_Height)
        {
            this.Animation_Form = An_Form;
            this.RefreshHandler = refreshHandler;
            this.Animation_width = An_Width;
            this.Animation_height = An_Height;
            BinTree_Data = new char[MAX_SIZE];
            BinTreeData = null;
            //设置画布和画笔
            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);
            NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_four.png");
            PosBmp = (Bitmap)Image.FromFile(path + "/image/deletepos.png");

            NSize = (Animation_height / 100) * 10;
        }

        /// <summary>
        /// 设置演示动画窗体的大小
        /// </summary>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        public void SetAnimationFormSize(int Width, int Height)
        {
            this.Animation_width = Width;
            this.Animation_height = Height;
        }

       

        private const int SPEED = 1000;
        private int _Speed = SPEED;//演示动画速度
        public void SetSpeed(float scale)
        {
            _Speed = (int)(SPEED * scale);
        }

        private bool stop_flag = false;//结束标志位

        /// <summary>
        /// 初始化或者恢复二叉树数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool ResetData(ref BinTreeNode data)
        {
            if (null == data)
            {
                return false;
            }
            BinTreeData = data;
            FingerNode = BinTreeData;
            BinTreeData.x = Animation_width / 2;
            BinTreeData.y = Animation_height / 5;
            return true;
        }

        private string BinTreeStrData;
        private string cur_StrData;//当前先序遍历字符串
        private string rem_StrData;//剩余先序遍历字符串
        public bool ResetData(string data)
        {
            if (null==data)
            {
                return false;
            }
            BinTreeStrData = data;
            BinTreeData = null;
            cur_StrData = "";
            rem_StrData = data;
            return true;
            
        }

        private List<BinTreeNode> HoffmanTreeArray = new List<BinTreeNode>();
        private List<int> HoffmanElemArray = new List<int>();
        public bool ResetData(string[] data)
        {
            HoffmanTreeArray.Clear();
            HoffmanElemArray.Clear();
            if (null == data)
            {
                return false;
            }
            for (int i = 0; i < data.Length;++i )
            {
                HoffmanElemArray.Add(Convert.ToInt32(data[i]));
                HoffmanTreeArray.Add(new BinTreeNode(data[i], null, null));
            }
            return true;
        }
        /// <summary>
        /// 动画演示主函数
        /// </summary>
        public void Animation()
        {
            switch (GlobalBinTree.operateType)
            {
                case OperateTypeBinTree.CreTree:
                    SetExcuteLine(1);
                    stop_flag = Animation_Creat(); 
                    break;
                case OperateTypeBinTree.PreOrder:
                    stop_flag = Animation_Pre(); 
                    break;
                case OperateTypeBinTree.InOrder:
                    stop_flag = Animation_In();
                    break;
                case OperateTypeBinTree.PostOrder:
                    stop_flag = Animation_Post();
                    break;
                case OperateTypeBinTree.Hoffman:
                    NSize = 40;
                    stop_flag = Animation_Hoffman();
                    break;
            }

            if (!stop_flag)
            {
                MessageBox.Show(Animation_Form,"算法演示结束!");
                 SysMainForm.AnimationForm.ChangeExcuteOverBtnsEnable();
            }

        }
        private bool Animation_Creat()
        {
            Orderstr = "剩余字符串：";
            BinTreePreCreat2(ref BinTreeData, ref rem_StrData);
            SetExcuteLine(13);
            if (!Refresh())
            {
                return false;
            }
            return false;
        }

        private BinTreeNode FingerNode;
        private BinTreeNode FingerNode_Next;
        /// <summary>
        /// 先序遍历动画演示
        /// </summary>
        public bool Animation_Pre()
        {
            Orderstr = "前序遍历结果：";
            BinTreePreOrder(BinTreeData);
            SetExcuteLine(6);
            if (!Refresh())
            {
                return false;
            }
            return false;
        }

        /// <summary>
        /// 中序遍历动画演示
        /// </summary>
        public bool Animation_In()
        {
            Orderstr = "中序遍历结果：";
            BinTreeInOrder(BinTreeData);
            if (!Refresh())
            {
                return false;
            }
            return false;
        }

        /// <summary>
        /// 后序遍历动画演示
        /// </summary>
        public bool Animation_Post()
        {
            Orderstr = "后序遍历结果：";
            BinTreePostOrder(BinTreeData);
            if (!Refresh())
            {
                return false;
            }
            return false;
        }
        List<BinTreeNode> HoffmantempTreeArray = new List<BinTreeNode>();
        private void ReDrawHoffmanTree()
        {
            DrawHoffmanElement(HoffmanElemArray, minpos1, minpos2);
            BinTreeNode tempnode = new BinTreeNode();
            HoffmantempTreeArray.Clear();
            for (int i = 0; i < HoffmanTreeArray.Count; ++i)
            {
                tempnode = HoffmanTreeArray[i];
                if (tempnode.lChild!=null)
                {
                    HoffmantempTreeArray.Add(tempnode);                   
                }
               
            }
            int startlocate = 0;
            for (int i = 0; i < HoffmantempTreeArray.Count; ++i)
            {
                int endlocate = 0;
                tempnode = HoffmantempTreeArray[i];
                endlocate = startlocate + TreeNodeSize(ref tempnode) * Animation_width / (GlobalBinTree.HoffmanData.Length+1);
                DrawBinTreeHoffman(ref tempnode, 1, TreeHeight(ref tempnode), startlocate, endlocate);
                startlocate = endlocate;
            }
            Refresh();
            Thread.Sleep(1000);
        }

        private int minpos1 = -1;
        private int minpos2 = -1;
        private int mindata1;
        private int mindata2;
        private Point[] hoffmanelemlocat;
        public bool Animation_Hoffman()
        {
            SetExcuteLine(1);
            hoffmanelemlocat = new Point[HoffmanElemArray.Count];
            for (int i = 0; i < HoffmanElemArray.Count;++i )
            {
                HoffmanTreeArray[i].x = hoffmanelemlocat[i].X = (i + 1) * Animation_width / (HoffmanElemArray.Count + 1) - NSize / 2;
                HoffmanTreeArray[i].y = hoffmanelemlocat[i].Y = 80;
            }
            SetExcuteLine(2);
            SetExcuteLine(3);
            minpos1 = minpos2 = -1;
            ReDrawHoffmanTree();
            SetExcuteLine(4);
            while (HoffmanElemArray.Count>1)
            {
                FingerNode = FingerNode_Next = null;
                SetExcuteLine(5);
                SetExcuteLine(6);
                HoffmanMaxMin(HoffmanElemArray, ref minpos1, ref mindata1, ref minpos2, ref mindata2);
                SetExcuteLine(7);
                FingerNode = HoffmanTreeArray[minpos1];
                SetExcuteLine(8);
                FingerNode_Next = HoffmanTreeArray[minpos2];
                ReDrawHoffmanTree();
                
                if (minpos1>minpos2)
                {
                    int temp;
                    temp = minpos1;
                    minpos1 = minpos2;
                    minpos2 = temp;
                }
                SetExcuteLine(9);
                SetExcuteLine(10);
                HoffmanElemArray.RemoveAt(minpos2);
                HoffmanElemArray.RemoveAt(minpos1);
                HoffmanElemArray.Add(mindata1+mindata2);
                int tempvalue = mindata1 + mindata2;
                BinTreeNode HoffmanMergerTree = new BinTreeNode("?", null, null);
                SetExcuteLine(11);
                HoffmanMergerTree.lChild = FingerNode = HoffmanTreeArray[minpos1];
                SetExcuteLine(12);
                HoffmanMergerTree.rChild = FingerNode_Next = HoffmanTreeArray[minpos2];
                HoffmanTreeArray.RemoveAt(minpos2);
                HoffmanTreeArray.RemoveAt(minpos1);
                HoffmanTreeArray.Add(HoffmanMergerTree);
                minpos1 = minpos2 = -1;
                ReDrawHoffmanTree();
                SetExcuteLine(13);
                HoffmanTreeArray[HoffmanTreeArray.Count - 1].data = tempvalue.ToString();
                FingerNode = FingerNode_Next = HoffmanTreeArray[HoffmanTreeArray.Count - 1];
                SetExcuteLine(14);
                ReDrawHoffmanTree();
                SetExcuteLine(4);               
            }
            
            return false;
        }
        private bool Refresh()
        {
            try
            {
                if (Animation_Form.IsHandleCreated)
                    Animation_Form.Invoke(RefreshHandler);
            }
            catch (Exception ex)
            {
                MessageBox.Show(Animation_Form,ex.Message);
                return false;
            }
            return true;
        }

        public string Orderstr = "遍历结果：";

        public void BinTreePreCreat2(ref BinTreeNode root, ref string str)
        {
            DrawTreeRefresh();
            SetExcuteLine(1);
            string tempstr = "";
            SetExcuteLine(2);
            SetExcuteLine(3);
            if (str=="")
            {
                SetExcuteLine(12);
                DrawTreeRefresh();
                return;
            }
            SetExcuteLine(4);
            tempstr = str[0].ToString();
            SetExcuteLine(5);
            if (tempstr!="#")
            {
                SetExcuteLine(6);
                root = new BinTreeNode("?");
                SetExcuteLine(7);
                if (root==null)
                {
                    SetExcuteLine(8);
                    return;
                }
                FingerNode = root;
                DrawTreeRefresh();
                SetExcuteLine(9);
                root.data = tempstr;
                DrawTreeRefresh();
                if (str.Length == 1)
                {
                    str = "";
                }
                else
                {
                    str = str.Remove(0,1);
                }
                SetExcuteLine(10);
                BinTreePreCreat2(ref root.lChild, ref str);
                FingerNode = root;
                DrawTreeRefresh();
                SetExcuteLine(11);
                BinTreePreCreat2(ref root.rChild, ref str);
                FingerNode = root;
                DrawTreeRefresh();
            }
            else
            {
                SetExcuteLine(12);
                if (str.Length == 1)
                {
                    str = "";
                }
                else
                {
                    str = str.Remove(0, 1);
                }
                DrawTreeRefresh();
            }

        }


        public void BinTreePreCreat(ref BinTreeNode root,ref string str)
        {
            SetExcuteLine(2);
            SetExcuteLine(3);
            if (rem_StrData=="")
            {
                BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
                DrawTreeRefresh();
                return;
            }
            string temp;
            if (rem_StrData[0]!='#')
            {
                str += "?";
                temp = str;
                ConStr_Root(ref root, ref temp);
                DrawTreeRefresh();
                if (str.Length==1)
                {
                    str = "";
                }
                else
                {
                    str = str.Remove(str.Length - 1);
                }
                str += rem_StrData[0];
                rem_StrData = rem_StrData.Remove(0, 1);
                temp = str;
                ConStr_Root(ref root, ref temp);
                DrawTreeRefresh();
                BinTreePreCreat(ref root, ref str);
            }
            else
            {
                str += rem_StrData[0];
                rem_StrData = rem_StrData.Remove(0, 1);
                temp = str;
                ConStr_Root(ref root, ref temp);
                DrawTreeRefresh();
                BinTreePreCreat(ref root, ref str);
            }
            
        }

        private void DrawTreeRefresh()
        {
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
            DrawBinTree(ref BinTreeData, 1, 5);
            BufferGrap.DrawString(Orderstr+rem_StrData, new Font("微软雅黑", 14), Brushes.Yellow, 50, Animation_height - 50);
            Refresh();
            Thread.Sleep(_Speed);
        }
        public void BinTreePreOrder(BinTreeNode root)
        {
            SetExcuteLine(1);
            if (null==root)
            {
                SetExcuteLine(6);
                DrawTreeRefresh();
                return;
            }
            FingerNode = root;
            SetExcuteLine(2);
            Orderstr += root.data;
            DrawTreeRefresh();
            SetExcuteLine(3);
            BinTreePreOrder(root.lChild);
            FingerNode = root;
            DrawTreeRefresh();
            SetExcuteLine(4);
            BinTreePreOrder(root.rChild);
            FingerNode = root;
            DrawTreeRefresh();
        }
        public void BinTreeInOrder(BinTreeNode root)
        {
            SetExcuteLine(1);
            if (null == root)
            {
                SetExcuteLine(6);
                DrawTreeRefresh();
                return;
            }
            FingerNode = root;
            DrawTreeRefresh();
            SetExcuteLine(2);
            BinTreeInOrder(root.lChild);
            SetExcuteLine(3);
            Orderstr += root.data;
            FingerNode = root;
            DrawTreeRefresh();
            SetExcuteLine(4);
            BinTreeInOrder(root.rChild);
            FingerNode = root;
            DrawTreeRefresh();
        }
        public void BinTreePostOrder(BinTreeNode root)
        {
            SetExcuteLine(1);
            if (null == root)
            {
                SetExcuteLine(6);
                DrawTreeRefresh();
                return;
            }
            FingerNode = root;
            
            DrawTreeRefresh();
            SetExcuteLine(2);
            BinTreePostOrder(root.lChild);
            FingerNode = root;
            DrawTreeRefresh();
            SetExcuteLine(3);
            BinTreePostOrder(root.rChild);
            SetExcuteLine(4);
            Orderstr += root.data;
            FingerNode = root;
            DrawTreeRefresh();
        }

        public int TreeHeight(ref BinTreeNode btn)
        {
            if (btn == null) return 0;	//空树高度为0
            else
            {
                int i = TreeHeight(ref btn.lChild);
                int j = TreeHeight(ref btn.rChild);
                return (i < j) ? j + 1 : i + 1;
            }
        }


        public int TreeNodeSize(ref BinTreeNode btn)
        {
	        if (btn == null) return 0;	       //空树
            else 
	        {
		        int n = 0;
                if (btn.lChild == null && btn.rChild == null) n = 1;
                return n + TreeNodeSize(ref btn.lChild) + TreeNodeSize(ref btn.rChild);
	        }
        }

        /// <summary>
        /// 绘制二叉树
        /// </summary>
        /// <param name="btn"></param>

        public void DrawBinTree(ref BinTreeNode btn, int levelnum,int levelsum)
        {
            NSize = (int)(Animation_width / (Math.Pow(2, levelsum - 1) + 1.0));
            NSize = (NSize > 80 ? 80 : NSize);
            int y = (int)(Animation_height * 1.0 / (levelsum + 1));
            int x = (int)(Animation_width / Math.Pow(2, levelnum));

           
            if (btn != null)
            {
                if (levelnum == 1)
                {
                    btn.x = x;
                    btn.y = y;
                }
                if (btn.lChild != null)
                {
                    btn.lChild.x = btn.x - x / 2;
                    btn.lChild.y = btn.y + y;
                    BufferGrap.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.lChild.x, btn.lChild.y));
                    DrawBinTree(ref btn.lChild, levelnum + 1, levelsum);
                }
                if (btn.rChild != null)
                {
                    btn.rChild.x = btn.x + x / 2;
                    btn.rChild.y = btn.y + y;
                    BufferGrap.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.rChild.x, btn.rChild.y));
                    DrawBinTree(ref btn.rChild, levelnum + 1, levelsum);
                }
                if (FingerNode == btn || FingerNode_Next == btn)
                {
                    NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_six.png");
                    if (GlobalBinTree.operateType==OperateTypeBinTree.Hoffman&&btn.lChild!=null)
                    {
                        NodeBmp = (Bitmap)Image.FromFile(path + "/image/node_2.png");
                    }

                    BufferGrap.DrawImage(NodeBmp, btn.x - NSize / 2, btn.y - NSize / 2, NSize, NSize);
                    BufferGrap.DrawImage(PosBmp, btn.x - PosSize / 2, btn.y-NSize/2 - PosSize, PosSize, PosSize);
                    BufferGrap.DrawString(btn.data, new Font("微软雅黑", 13), Brushes.Yellow, btn.x - NSize / 2 + NSize / 5, btn.y - NSize / 2 + NSize / 5);
                }
                else
                {
                    NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_four.png");
                    if (GlobalBinTree.operateType == OperateTypeBinTree.Hoffman && btn.lChild != null)
                    {
                        NodeBmp = (Bitmap)Image.FromFile(path + "/image/node_1.png");
                    }
                    BufferGrap.DrawImage(NodeBmp, btn.x - NSize / 2, btn.y - NSize / 2, NSize, NSize);
                    BufferGrap.DrawString(btn.data, new Font("微软雅黑", 13), Brushes.Yellow, btn.x - NSize / 2 + NSize / 5, btn.y - NSize / 2 + NSize / 5);
                }
            }
        }



        /// <summary>
        /// 绘制霍夫曼树
        /// </summary>
        /// <param name="btn"></param>

        public void DrawBinTreeHoffman(ref BinTreeNode btn, int levelnum, int levelsum,int WS,int WE)
        {
            NSize = (int)((WE - WS) / (Math.Pow(2, levelsum - 1) + 1.0));
            NSize = (NSize > 40 ? 40 : NSize);
            int x = (int)((WE - WS) / Math.Pow(2, levelnum));
            int y = (int)(Animation_height * 1.0 / (levelsum + 1));


            if (btn != null)
            {
                if (levelnum == 1)
                {
                    btn.x = x + WS;
                    btn.y = y;
                }
                if (btn.lChild != null)
                {
                    btn.lChild.x = btn.x - x / 2;
                    btn.lChild.y = btn.y + y;
                    BufferGrap.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.lChild.x, btn.lChild.y));
                    DrawBinTreeHoffman(ref btn.lChild, levelnum + 1, levelsum, WS, WE);
                }
                if (btn.rChild != null)
                {
                    btn.rChild.x = btn.x + x / 2;
                    btn.rChild.y = btn.y + y;
                    BufferGrap.DrawLine(new Pen(Color.Blue, 3), new Point(btn.x, btn.y), new Point(btn.rChild.x, btn.rChild.y));
                    DrawBinTreeHoffman(ref btn.rChild, levelnum + 1, levelsum, WS, WE);
                }
                if (FingerNode == btn || FingerNode_Next == btn)
                {
                    NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_six.png");
                    if (GlobalBinTree.operateType == OperateTypeBinTree.Hoffman && btn.lChild != null)
                    {
                        NodeBmp = (Bitmap)Image.FromFile(path + "/image/node_2.png");
                    }

                    BufferGrap.DrawImage(NodeBmp, btn.x - NSize / 2, btn.y - NSize / 2, NSize, NSize);
                    BufferGrap.DrawImage(PosBmp, btn.x - PosSize / 2, btn.y - NSize / 2 - PosSize, PosSize, PosSize);
                    BufferGrap.DrawString(btn.data, new Font("微软雅黑", 13), Brushes.Yellow, btn.x - NSize / 2 + NSize / 5, btn.y - NSize / 2 + NSize / 5);
                }
                else
                {
                    NodeBmp = (Bitmap)Image.FromFile(path + "/image/ball_four.png");
                    if (GlobalBinTree.operateType == OperateTypeBinTree.Hoffman && btn.lChild != null)
                    {
                        NodeBmp = (Bitmap)Image.FromFile(path + "/image/node_1.png");
                    }
                    BufferGrap.DrawImage(NodeBmp, btn.x - NSize / 2, btn.y - NSize / 2, NSize, NSize);
                    BufferGrap.DrawString(btn.data, new Font("微软雅黑", 13), Brushes.Yellow, btn.x - NSize / 2 + NSize / 5, btn.y - NSize / 2 + NSize / 5);
                }
            }
        }

        public void DrawHoffmanElement(List<int> str,int pos1,int pos2)
        {
            if (null == str)
            {
                return;
            }
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
            for (int i = 0; i < str.Count;++i )
            {
                int x = (i + 1) * Animation_width / (str.Count + 1) - NSize / 2;
                int y = 20;
                HoffmanBmp = (Bitmap)Image.FromFile(path + "/image/node_four.png");
                if (i==pos1||i==pos2)
                {
                    HoffmanBmp = (Bitmap)Image.FromFile(path + "/image/node_nine.png");
                }
                BufferGrap.DrawImage(HoffmanBmp,x , y, 50, 50);
                BufferGrap.DrawString(str[i].ToString(), new Font("微软雅黑", 18), Brushes.Blue, x + NSize / 5, y + NSize / 5);
            }
        }

        private void HoffmanMaxMin(List<int> str,ref int minpos1,ref int mindata1,ref int minpos2,ref int mindata2 )
        {
            mindata1 = str[0];
            mindata2 = str[1];
            minpos1 = 0;
            minpos2 = 1;
            for (int i = 0; i < str.Count; ++i)
            {
                if (str[i]<mindata1&&i!=minpos2)
                {
                    mindata1 = str[i];
                    minpos1 = i;
                }
            }
            for (int i = 0; i < str.Count; ++i)
            {
                if (str[i] < mindata2 && i!=minpos1)
                {
                    mindata2 = str[i];
                    minpos2 = i;
                }
            }
 
        }

        //重新设置双缓冲画布和Graphics
        public void ResetBuffer(int Width, int Height)
        {
            this.Animation_width = Width;
            this.Animation_height = Height;
            if (null != BufferBmp)
            {
                BufferBmp.Dispose();
                BufferBmp = null;
            }
            if (null != BufferGrap)
            {
                BufferGrap.Dispose();
                BufferGrap = null;
            }

            BufferBmp = new Bitmap(this.Animation_width, this.Animation_height);
            BufferGrap = Graphics.FromImage(BufferBmp);
            DrawBinTree(ref BinTreeData, 1, TreeHeight(ref BinTreeData));
        }

        /// <summary>
        /// 将二叉树：链式存储结构→先序遍历字符串
        /// </summary>
        /// <param name="btn"></param>
        /// <param name="str"></param>
        /// 
        private void ConStr_Root(ref BinTreeNode btn, ref string str)
        {
            if (str == "")
            {
                btn = null;
                return;
            }

            if (str[0].ToString() == "" || str[0].ToString() == "#")
            {
                btn = null;
                str = str.Remove(0, 1);
                return;
            }
            btn = new BinTreeNode();
            if (btn == null)
            {
                return;
            }
            btn.data = str[0].ToString();
            FingerNode = btn;
            str = str.Remove(0, 1);
            ConStr_Root(ref btn.lChild, ref str);
            ConStr_Root(ref btn.rChild, ref str);
        }


        private void ConStr_Root2(ref BinTreeNode btn, ref string str)
        {
            SetExcuteLine(3);
            SetExcuteLine(4);
            SetExcuteLine(5);
            if (str == "")
            {
                SetExcuteLine(12);
                btn = null;
                return;
            }
            
            if (str[0].ToString() == "" || str[0].ToString() == "#")
            {
                SetExcuteLine(12);
                btn = null;
                str = str.Remove(0, 1);
                return;
            }
            SetExcuteLine(6);
            btn = new BinTreeNode();
            SetExcuteLine(7);
            if (btn==null)
            {
                SetExcuteLine(8);
                return;
            }
            SetExcuteLine(9);
            btn.data = str[0].ToString();
            FingerNode = btn;
            str = str.Remove(0, 1);
            SetExcuteLine(10);
            ConStr_Root(ref btn.lChild, ref str);
            SetExcuteLine(11);
            ConStr_Root(ref btn.rChild, ref str);
        }

        public void InitData()
        {
            ResetBuffer(Animation_width, Animation_height);
            switch (GlobalBinTree.operateType)
            {
                case OperateTypeBinTree.CreTree:
                    ResetData(GlobalBinTree.pretreedata);break;
                case OperateTypeBinTree.PreOrder:
                case OperateTypeBinTree.InOrder:
                case OperateTypeBinTree.PostOrder:
                    ResetData(ref GlobalBinTree.treeroot); break;
                case OperateTypeBinTree.Hoffman:
                    ResetData(GlobalBinTree.HoffmanData); break;
            }
            BufferGrap.DrawImage(PublicDataClass.DemoPicture, 0, 0, Animation_width, Animation_height);
            DrawBinTree(ref BinTreeData, 1, 5);
            Refresh();
        }
        public void ResetData()
        {
            InitData();
        }
        public Bitmap GetBufferBmp()
        {
            return BufferBmp;
        }
        private void SetExcuteLine(int line)
        {
            if (line != GlobalBinTree.cur_line)
            {
                GlobalBinTree.cur_line = line;
                Thread.Sleep((int)(1000 * PublicDataClass.scale));
                SysMainForm.AnimationForm.SetSelectLine(line);
            }
        }
    }
}

